#pragma once
#include <queue>
#include "base/core/os/thread.h"
#include "base/core/os/mutex.h"
#include "DBOption/Mysql/MysqlConnector.h"
#include "DBOption/Redis/RedisConnector.h"
#include "DBFlushDefine.h"
#include <string>

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#pragma warning(disable:4244) //conversion from '__int64' to 'int', possible loss of data
#pragma warning(disable:4267) //conversion from 'size_t' to 'int', possible loss of data
#pragma warning(disable:4127) //conditional expression is constant
#endif

#include "ProtoBuffer/ComProtocol.pb.h"
#include "Common/CharacterDefine.h"

#ifdef _MSC_VER
#pragma warning(pop)
#endif

using namespace ProtoBuf;
using namespace std;

class DBFlushThread 
{
private:
	static const int maxCommonLength = 1024 * 96 * 10;

	Thread m_thread;

	DB_FLUSH_START_PARAM m_param;
	const char * m_dbname;
	uint32_t m_groupId;
	MysqlConnector m_mysqlConnector;
	RedisConnector m_redisConnector;

	uint32_t m_flushFrequency;
	bool m_threadExitFlag;
	bool m_threadWorkingFlag;
	char m_command[maxCommonLength];
	char m_groupCommand[maxCommonLength];

public:
    DBFlushThread();
    ~DBFlushThread();

    bool Start(const DB_FLUSH_START_PARAM& dbFlushStartParam);
    bool Stop();

private:
	typedef bool (DBFlushThread::*ProcessFunction)(CharIDType id);
	static ProcessFunction ms_FunctionTable[];
    static void _ThreadFunctionProxy(void *param);

    bool _ConnectDatabase();
    bool _ThreadFunction();
    bool _ProcessFlush(int currentType, bool all);
    bool _ProcessGroupData(int currentType, bool all);
	bool _ProcessError(const char* command, int currentType, CharIDType id);
	bool _SetUpdateToMysqlFlag(DB_FLUSH_EVENT_TYPE type, CharIDType id, DBFLUSH_UPDATE_STATE charUpdateState);

    bool _GetDataRedis(const string& key, string& data);
    bool _SetDataRedisExpire(const string& key);
	bool _DelCharacterDataRedis(CharIDType charId);

    bool _CreateMysqlData(const string& key, const string& data, string& sqlExec);
    bool _UpdateMysqlData(const string& key, const string& data, string& sqlExec);
    bool _DeleteMysqlData(const string& key, const string& data, string& sqlExec);

	//-------------------------------------------------------------------------------------------------------
	bool _GetCharacterDataRedis(CharIDType charId, CharacterDBInfo* retCharInfo);
	bool _SetCharacterDataMysql(CharIDType charId, const CharacterDBInfo& charInfo);
	bool _DelCharacterDataMysql(CharIDType charId);
	bool _SetCharacterDataExpire(CharIDType charId);

	bool _flush_character(CharIDType id);
	bool _delete_character(CharIDType id);
};